#ifndef ROBOWALKER_AUTOAIMING_POWERRUNEDETECTION_H
#define ROBOWALKER_AUTOAIMING_POWERRUNEDETECTION_H
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>
#include <numeric>
#include <chrono>
#include "CurveFitter.h"
#include <deque>

using namespace cv;
using namespace std;

class PowerRuneDetector {
public:
    enum class PowerRuneColor
    {
        Blue = 0,
        Red 
    };
    enum class RotateDirection
    {
        counterclockwise = 0,
        clockwise = 1, 
    };

    PowerRuneDetector(const double fps);
    bool detect(Mat srcImage, bool predict_mode, double delay, double delta_x, double delta_y, Point2f& detectPoint, Point2f &target_point);
    void setPowerRuneColor(const string& color); 

    friend class CurveFitter; 

private:
    deque<Point2f> cirV;
    deque<Point2f> predV;
    Point2f cc;
    double R;
    double fps;
    vector<double> real_spd;
    bool is_tracking;
    Rect2d bbox;
    Mat templ[9];
    double template_max;
    bool template_dir;
    double thr;
    PowerRuneColor PRcolor; 
    const double circleFitDataNumThresh = 20; 
    const double circleFitDataNumUpperBound = 25; 
    const double predictDataNumThresh = 20; 
    const double predictDataNumUpperBound = 21; 


    // CurveFitter curveFitter; 

    int Compare(double* spd, int n);
    void predict(bool mode, double delay, deque<Point2f> sampled_pts, Point2f& p, bool clearflag);
    
    // The functions below are used in detect() function 
    double TemplateMatch(cv::Mat image, cv::Mat tepl, cv::Point2f& point, int method);
    void preprocess(Mat& img);
    void leafImageTemplateMatch(Mat& leaf_img);
    void getPowerRuneArmorBoxCenter(Vec4i& hierarchy, vector<vector<Point>>& contours2, RotatedRect& rect_tmp2, 
                                    Point2f& centerP, Point2f& offset, Mat& img, Mat& srcImage);
    // void circleAndCurveFitting(bool clearflag, Point2f centerP,  
    //                             Point2f& predictArmorBoxCenter, Point2f delta_p, Mat& drawcircle);
    void circleFitting(bool clearflag, Point2f centerP, Point2f delta_p, Mat& drawcircle);
    void getTargetROI(RotatedRect& rect_tmp2, Mat& srcImage, Point2f offset); 

    void detectDebug(); 
};


#endif //ROBOWALKER_AUTOAIMING_PowerRuneDETECTION_H
